
class Proto(object):
    
    def __init__(self, module_name='generated', package=None):
        """
        Args:
        module_name - (str) The name of the python module that
                           will be generated for this Protocol Buffer
        
        Args:
        package - (str) Option value indicating java package for generated code
        """
        self.module_name = module_name
        self.package     = package
        self.imports     = []
        self.enums       = {}
        self.messages    = {}
        self.services    = {}
        
    
    def python_mod_name(self):
        return self.module_name + "_pb2"
    
    
    def proto_filename(self):
        return self.module_name + ".proto"
    
    
    def add_import(self, proto):
        """ Add a Proto to be imported
        If supplied as a string the proto must be the path relative to the
        -I/--proto_path option that will be supplied when the protocol buffer
        compiler is invoked
        
        Args:
        proto - (str or Proto) -
        """
        self.imports.append(proto)
    
    
    def add_enum(self, enum):
        """ Add an Enum to this Protocol Buffer
        
        Args:
        enum - (Enum) - Enum to be added
        """
        self.enums[enum.name] = enum
    
          
    def add_msg(self, message):
        """ Add a Message to this Protocol Buffer.
        
        Args:
        message - (Message) The message to be added
        """
        if self.messages.has_key(message.name):
            print "Warning: Collision in .proto definition on message name " + message.name + ". Attempting to merge messages."
            print self.messages[message.name], message
            new_msg = self.messages[message.name].merge(message)
            print "merged message", new_msg
            self.messages[message.name] = new_msg
#            raise Exception("Collision on message name, " + message.name)
        else:
            self.messages[message.name] = message
       
     
    def add_service(self, service):
        """ Add a service to this Protocol Buffer.
        
        Args:
        service - (Service) A service to be added
        """
        self.services[service.name] = service
    
    
    def __str__(self):
        """ Produce a .proto file string for this Protocol Buffer
            instance
        """
        # Header
        out= "//Protocol Buffer file generated by pbandj.\n\n"
        out += "//Required as of protobuf version 2.4.0 to generate service stubs.\n"
        
        # Options
        out += "option py_generic_services = true;\n"
        out += "option java_generic_services = true;\n\n"
        if self.package:
            out += "option java_package = \"" + self.package + "\";\n"
            
        # Imports
        imported_msgs = []
        for proto in self.imports:
            if isinstance(proto, Proto):
                imported_msgs += proto.messages.values()
                out += 'import "%s";\n' % proto.proto_filename()
            else:
                out += 'import "%s";\n' % proto
        if len(self.imports) > 0:
            out += "\n"
        
        # Enums
        for enum_name, enum in self.enums.items():
            out += str(enum)
        
        # Messages
        for msg_name, msg in self.messages.items():
            out += str(msg) + "\n"
        
        # Services
        for service_name, service in self.services.items():
            out += str(service)
            out += "\n"
            
        return out